package ar.edu.unlu.sistemas.ws.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ResultsLogProcessor {
	
	private static String current = QueriesLogProcessor.UMEX_SORT;
	private static final String QUERY_TEMPLATE = "<query><type>indri</type><number>@@query_id@@</number><text>@@query@@</text></query>";
	private static Map<String,List<Integer>> ip_peerIds = new HashMap<String, List<Integer>>();
	private static Map<String,QueryResults> query_results = new HashMap<String, QueryResults>();
	
	public static void main(String[] args) throws IOException, ParseException {
		Matcher m;
		String line;
		Double ranking;
		QueryResults qr;
		
		Pattern patSayHello = Pattern.compile(".*sayHello\\s-\\sRetorno\\s\\d+\\sal\\speer\\sPeer\\((\\d+)\\)\\[addr\\:([\\d+\\.]+).*");
		Pattern patQuery = Pattern.compile(".*Retorno\\srespuesta\\sde\\squery\\s\"([\\w\\d\\s]+)\".*");
		String regexResult = "\\tResultados.*";
		Pattern patList = Pattern.compile("\\t\\t(.+\\.txt)\\s-\\s(\\d\\.\\d+)\\s\\(([\\d+\\.]+)\\:\\d+\\)");
		Pattern patCori = Pattern.compile(".*\\s-\\scori\\s-\\sINFO\\s-\\sResultados\\sarrojados\\spor\\sCORI\\s\\(peerId\\:[\\w\\d]+\\)\\spara\\squery\\s\"([\\w\\d\\s]+)\"\\s\\[(\\[peerId\\:(\\d+)\\-rank\\:(\\d+\\.\\d+)\\]\\,\\s\\[peerId\\:(\\d+)\\-rank\\:(\\d+\\.\\d+)\\]\\,\\s\\[peerId\\:(\\d+)\\-rank\\:(\\d+\\.\\d+)\\])\\].*");	

		int counter = 0;
		
		
		FileWriter writer_params = new FileWriter(new File("/home/pepo/Dropbox/Tesis/lemur/bin/params_query_"+current.toUpperCase()));
		BufferedReader br = new BufferedReader(new FileReader(new File("/home/pepo/Dropbox/Tesis/Logs_Prueba_Grande/logs_"+current.toUpperCase()+"/web-service.log")));
		
		writer_params.append("<parameters>");
		while((line = br.readLine())!=null) {
			if ((m = patQuery.matcher(line)).matches()) {
				qr = new QueryResults(m.group(1).trim(), counter++);
				query_results.put(qr.query,qr);
				writer_params.append(QUERY_TEMPLATE.replaceFirst("@@query_id@@", String.valueOf(qr.id)).replaceFirst("@@query@@",qr.query));
				if ((line = br.readLine())!=null && Pattern.matches(regexResult, line)) {
					while ((line = br.readLine())!=null && (m =patList.matcher(line)).matches()) {
						ranking = Double.parseDouble(m.group(2));
						qr.documents.add(new DocumentRow(m.group(1),ranking,m.group(3)));
					}
				}
			} else if ((m = patSayHello.matcher(line)).matches()) {
				if(!ip_peerIds.containsKey(m.group(2))) ip_peerIds.put(m.group(2), new ArrayList<Integer>());
				ip_peerIds.get(m.group(2)).add(Integer.parseInt(m.group(1)));
			}
		}
		br.close();
		writer_params.append("<baseline>tfidf</baseline></parameters>");
		writer_params.flush();
		writer_params.close();
		
		System.out.println("\n// IDs DE LOS PEERS //");
		for (String ip : ip_peerIds.keySet()) {
			System.out.println(ip+" -> "+ip_peerIds.get(ip).toString());
		}
		
		br = new BufferedReader(new FileReader(new File("/home/pepo/Dropbox/Tesis/Logs_Prueba_Grande/logs_"+current.toUpperCase()+"/cori.log")));
		while((line = br.readLine())!=null) {
			if ((m = patCori.matcher(line)).matches()) {
				if (query_results.containsKey(m.group(1).trim())) {
					for (int i = 3; i < m.groupCount(); i+=2) {
						query_results.get(m.group(1).trim()).sources.add(new SourceRow(getPeerIPById(new Integer(m.group(i))),Double.parseDouble(m.group(i+1))));
					}
				}
			}
		}
		br.close();
		
		
		System.out.println("\n// RESULTADOS DE LAS QUERIES //");
		for (String q : query_results.keySet()) {
			System.out.println(query_results.get(q).toString());
		}
		ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("/home/pepo/Dropbox/Tesis/Resultados/"+current.toUpperCase()+"_result_object")));
		oos.writeObject(query_results);
		oos.close();
	}
	
	private static String getPeerIPById(Integer id) {
		for (String ip : ip_peerIds.keySet()) {
			if (ip_peerIds.get(ip).contains(id)) return ip;
		}
		return "";
	}
	
	public static class QueryResults implements Serializable {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1519626409132376671L;
		QueryResults (String query,Integer id){
			this.query = query;
			this.id = id;
		}
		String query;
		Integer id;
		List<DocumentRow> documents = new ArrayList<DocumentRow>();
		List<SourceRow> sources = new ArrayList<SourceRow>();
		public String toString() {
			StringBuffer sb = new StringBuffer();
			sb.append("ID:");
			sb.append(this.id);
			sb.append("-QUERY:");
			sb.append(this.query);
			sb.append("-SOURCES:[");
			for (int i = 0; i<this.sources.size(); i++) {
				sb.append(" ");
				sb.append(i+1);
				sb.append(") ");
				sb.append(this.sources.get(i).toString());
				sb.append(" |");
			}
			sb.append("]-DOCS:[");	
			for (int i = 0; i<this.documents.size(); i++) {
				sb.append(" ");
				sb.append(i+1);
				sb.append(") ");
				sb.append(this.documents.get(i).toString());
				sb.append(" |");
			}
			sb.append("]");
			return sb.toString();
		}
	}
	
	public static class DocumentRow implements Serializable {
		/**
		 * 
		 */
		private static final long serialVersionUID = 2978184887870246713L;
		DocumentRow (String docName,Double rank,String source) {
			this.docName = docName.replaceAll("\\s", "_");
			this.rank = rank;
			this.source = source;
		}
		String docName;
		Double rank;
		String source;
		public String toString() {
			return "DOC:"+this.docName+"-RANK:"+this.rank+"-SOURCE:"+this.source;
		}
		@Override
		public boolean equals(Object obj) {
			if (obj instanceof DocumentRow) {
				DocumentRow dr = (DocumentRow)obj;
				return this.docName.trim().equals(dr.docName.trim());
			} else return false;
		}
	}
	
	public static class SourceRow implements Serializable {
		/**
		 * 
		 */
		private static final long serialVersionUID = 2010678831081077537L;
		SourceRow (String source, Double rank) {
			this.source = source;
			this.rank = rank;
		}
		String source;
		Double rank;
		public String toString() {
			return "SOURCE:"+this.source+"-RANK:"+this.rank;
		}
	}

}
